/*
 * Copyright (c) Jan Šlahora (${USER}) - 2012.
 * Created in IntelliJ IDEA 10.5
 */

package statistics;

import java.math.BigDecimal;
import statistics.Pocitani;

/*
*   File Poisson 
*   in package statistics
*   was created by slaha
*   on 28.2.12 at 14:57.
*
*/


public class Poisson {
  double lambda;
  double chi;


  public Poisson(Object[] hodnoty, Object[] pocty) {
    this.lambda = spoctiLambda(hodnoty, pocty);
  }

  public Poisson(double lambda) {
    this.lambda = lambda;
  }

  public double poissonovoRozdeleni(int k) throws Exception {
    if (k < 0 || lambda < 0) {
      throw new Exception("Parameter can't be less than zero");
    }
    //.. citatel
    BigDecimal citatel = new BigDecimal(Math.pow(lambda, k));
    //..jmenovatel
    BigDecimal jmenovatel;
    try {
      jmenovatel = new BigDecimal(Pocitani.faktorial(k));
    } catch (Exception e) {
      jmenovatel = BigDecimal.ONE.negate();
      System.err.println("Can't compute factorial");
      return -1;
    }

    BigDecimal zlomek = citatel.divide(jmenovatel, 15, BigDecimal.ROUND_HALF_UP);

    BigDecimal eNaLambda = new BigDecimal(Math.pow(Math.E, (-(lambda))));

    BigDecimal poisson = zlomek.multiply(eNaLambda);

    return poisson.doubleValue();
  }

  private double spoctiLambda(Object[] hodnoty, Object[] pocty) {
    double pocatecniOdhad = dejPocatecniOdhad(dejDoublePole(hodnoty), dejDoublePole(pocty));
    
    return pocatecniOdhad;
  }

  private double dejPocatecniOdhad(double[] i, double[] Xi) {
    double suma = 0;
    for (int x = 0; x < i.length; x++) {
      suma += i[x] * Xi[x];
    }
    double n = dejN(Xi);
    return ((1/n) * suma);
  }

  private double dejN(double[] Xi) {
    double n = 0;
    for (int i = 0; i < Xi.length; i++) {
      n += Xi[i];
    }
    return n;
  }

  private static double[] dejDoublePole(Object[] pole) {
    double[] doubles = new double[pole.length];
    for (int i = 0; i < pole.length; i++) {
      doubles[i] = new Double(pole[i].toString());
    }
    return doubles;
  }

  public double getLambda() {
    return lambda;
  }
}


